package com.cloud.ebookreader.access.library;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.Channels;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.cloud.ebookreader.access.Book;
import com.cloud.ebookreader.access.Library;
import com.cloud.ebookreader.opf.OcfEpubBook;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.files.AppEngineFile;
import com.google.appengine.api.files.FileReadChannel;
import com.google.appengine.api.files.FileService;
import com.google.appengine.api.files.FileServiceFactory;
import com.google.appengine.api.files.LockException;

public class UserLibrary implements Library{
	public static class BookCover {

        private String author = "Unknown";
        private String title;
        private String id;
        public BookCover() {
        }

        /**
         * @return the author
         */
        public String getAuthor() {
            return author;
        }

        /**
         * @param author the author to set
         */
        public void setAuthor(String author) {
            this.author = author;
        }

        /**
         * @return the title
         */
        public String getTitle() {
            return title;
        }

        /**
         * @param title the title to set
         */
        public void setTitle(String title) {
            this.title = title;
        }

        /**
         * @return the id
         */
        public String getId() {
            return id;
        }

        /**
         * @param id the id to set
         */
        public void setId(String id) {
            this.id = id;
        }
    }

	static final org.apache.log4j.Logger LOG = Logger.getLogger(UserLibrary.class);
	Map<String, Long> createdDates = new HashMap<String, Long> ();
	Map<String, Book> cache = new HashMap<String, Book> ();
	private static final long maxBookAge = 1000*60*60*5; // 5mins
	
	public UserLibrary() {}
	
	
	
	@Override
	public List<String> list() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public synchronized Book getBook(String bookBlobKey) throws Exception {
		//sample-ebook
		BlobKey blobKey = new BlobKey(bookBlobKey);
		
		FileService fileService = FileServiceFactory.getFileService();
		
		AppEngineFile file = null;
		try {
			file = fileService.getBlobFile(blobKey);
		} catch (FileNotFoundException e) {
			LOG.debug("getImageBytes_V2(): Error: fileService error "
					+ e.toString());
			e.printStackTrace();
		}
		
		if (file == null ) {
			return null;
		}
		
		FileReadChannel ch = null;
		try {
			ch = fileService.openReadChannel(file, false);
		} catch (FileNotFoundException e) {
			LOG.debug("getImageBytes_V2(): Error: file not found "
					+ e.toString());
			e.printStackTrace();
		} catch (LockException e) {
			LOG.debug("getImageBytes_V2(): Error: lock exception "
					+ e.toString());
			e.printStackTrace();
		} catch (IOException e) {
			LOG.debug("getImageBytes_V2(): Error: file read channel - io exception "
					+ e.toString());
			e.printStackTrace();
		}
		
		if (ch == null) {
			return null;
		}
		
		InputStream in = Channels.newInputStream(ch);
		
		OcfEpubBook book = new OcfEpubBook(in);
        in.close();
        createdDates.put(bookBlobKey, System.currentTimeMillis());
        cache.put(bookBlobKey, book);

        cleanLibrary();
        return book;
	}

	@Override
	public List<BookCover> detailList() {
		// TODO Auto-generated method stub
		return null;
	}
	
	private void cleanLibrary(){
        for(String k : createdDates.keySet()){
            long age = System.currentTimeMillis()-createdDates.get(k);
            if(age>maxBookAge){
                LOG.info("Removing Book "+k+" from Cache because its too old");
                
            }
        }
    }
}
